home *** CD-ROM | disk | FTP | other *** search
- /* DisplayLogDCMD.c */
- /*
- * DisplayLogDCMD.c
- * Copyright © 1992-95 Apple Computer Inc. All Rights Reserved.
- * Programmed by Martin Minow,
- * Internet: minow@apple.com
- * AppleLink: MINOW
- * Version of December 17, 1994
- *
- * Edit History
- * 93.01.09 MM First public release
- * 93.01.14 MM Think and MPW generate different record sizes;
- * a disaster if you create an Audit Record under
- * Think and call Audit compiled under MPW. Also
- * added a test for record sizes and included
- * record size information in the AuditRecord.
- * 94.07.18 MM Updated for the new semaphore stuff.
- * 94.12.17 MM Converted to the LogLibrary for Power PC
- * 95.01.21 MM Finally got around to debug the DCMD.
- * 95.05.05 MM Removed "enable on/off", use LogLibrary68
- * 95.05.26 MM Folded LogLibrary68 back into LogLibrary.
- *
- * This is a MacsBug DCMD that can display LogRecord contents.
- *
- * The following commands are supported:
- *
- * DisplayLog NAME Display the specified log (including previously
- * displayed elements that can be recovered).
- * DisplayLog Display all Log Records.
- *
- * DisplayLog is built by the provided Makefile.
- *
- * This file contains routines that were copied from the Display Log library.
- */
- #include <Errors.h>
- #include <Finder.h>
- #include <Folders.h>
- #include <Script.h>
- #include <Types.h>
- #include <Resources.h>
- #include <QuickDraw.h>
- #include <Fonts.h>
- #include <Events.h>
- #include <Windows.h>
- #include <Menus.h>
- #include <TextEdit.h>
- #include <Dialogs.h>
- #include <ToolUtils.h>
- #include <Memory.h>
- #include <Files.h>
- #include <OSUtils.h>
- #include <OSEvents.h>
- #include <Printing.h>
- #include <Traps.h>
- #include <Gestalt.h>
- #include <Processes.h>
- #include <StandardFile.h>
- #include <LowMem.h>
- #include "::Src:LogLibrary.h"
- /*
- * This file should be copied from the MacsBug distribution. Note
- * that we have our own display routines: only dcmdDrawString,
- * dcmdDrawLine, and dcmdDrawText are used.
- */
- #include "dcmd.h"
- #define DEBUG_DCMD 1
-
- #ifndef DEBUG_DCMD
- #define DEBUG_DCMD 0
- #endif
-
- #ifndef TRUE
- #define TRUE 1
- #define FALSE 0
- #endif
- enum {
- NUL = 0,
- kOpenQuote = 0xD2,
- kCloseQuote = 0xD3
- };
- #define kLogLinkFailed ((UniversalProcPtr) (-1L))
-
- void DCMDDoAllLogRecords(void);
- void DCMDDoThisLogRecord(
- LogRecordPtr logRecordPtr
- );
- void DCMDDoLogEntryRange(
- LogRecordPtr logRecordPtr,
- UInt32 startIndex,
- UInt32 endIndex
- );
- #define AppendChar(result, theChar) do { \
- StringPtr _dst = (result); \
- _dst[++_dst[0] & 0xFF] = theChar; \
- } while (0)
- void PutUnsignedLeadingZeros(
- UInt32 value,
- short digits,
- unsigned char terminator
- );
- void PutHexLeadingZeros(
- UInt32 value,
- short digits
- );
- void PutUnsigned(
- UInt32 value
- );
- void PutSigned(
- SInt32 value
- );
- void PutUnsignedInField(
- UInt32 value,
- short fieldWidth
- );
- void PutChar(
- unsigned char datum
- );
- void PutPascalString(
- ConstStr255Param datum
- );
- void PutCString(
- const char *datum
- );
- pascal void CommandEntry(
- dcmdBlock *paramPtr
- );
- pascal void dcmdSwapWorlds(void);
- void PutLine(void);
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * CommandEntry
- *
- * Here's where the DCMD "manager" calls us.
- */
- pascal void
- CommandEntry(
- dcmdBlock *paramPtr
- )
- {
- Str255 logRecordName;
- LogRecordPtr logRecordPtr;
-
- switch (paramPtr->request) {
- case dcmdInit:
- (void) GetLogRecordPtr(""); /* Force CodeFragment load */
- if (1) { /* Testing only */
- OSErr status;
- THz currentHeap;
- CFragConnectionID connectionID;
- Ptr mainEntryAddr;
- Str255 errorName;
-
- currentHeap = GetZone();
- SetZone(SystemZone());
- status = GetSharedLibrary(
- "\pLogLibrary",
- kPowerPCCFragArch,
- kLoadCFrag,
- &connectionID,
- &mainEntryAddr,
- errorName
- );
- SetZone(currentHeap);
- if (status != noErr) {
- PutPascalString("\pNo LogLibrary: ");
- PutSigned(status);
- PutPascalString("\p - ");
- PutPascalString(errorName);
- PutLine();
- }
- }
- break;
- case dcmdDoIt:
- dcmdSwapWorlds(); /* TMON needs this */
- logRecordName[0] = 0;
- (void) dcmdGetNextParameter(logRecordName);
- if (logRecordName[0] == 0)
- DCMDDoAllLogRecords();
- else {
- PutPascalString("\pLogRecord \"");
- PutPascalString(logRecordName);
- PutPascalString("\p\"");
- PutLine();
- /*
- * Convert the Pascal string to a CString.
- */
- logRecordName[logRecordName[0] + 1] = NUL;
- logRecordPtr = GetLogRecordPtr((char *) &logRecordName[1]);
- if (logRecordPtr == NULL) {
- PutPascalString("\p\"");
- PutPascalString(logRecordName);
- PutPascalString("\p\" was not found");
- PutLine();
- dcmdSwapWorlds();
- goto drawHelp;
- }
- else {
- PutLine();
- DCMDDoThisLogRecord(logRecordPtr);
- }
- }
- dcmdSwapWorlds(); /* TMON needs this */
- break;
- case dcmdHelp:
- dcmdDrawLine("\pDisplayLog formats LogRecord areas.");
- drawHelp: dcmdDrawLine("\pFormat:");
- dcmdDrawLine("\pDisplayLog Write all Log Records.");
- dcmdDrawLine("\pDisplayLog NAME Write this Log Record only.");
- dcmdDrawLine("\p");
- break;
- }
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * DCMDDoAllLogRecords
- *
- * Enumerate through the Log Record entries in the Name Registry.
- */
- void
- DCMDDoAllLogRecords(void)
- {
- OSErr status;
- LogRecordIter cookie;
- LogRecordPtr logRecordPtr;
- UInt32 count;
-
- /*
- * First pass just lists the records.
- */
- status = LogRecordIterateCreate(&cookie);
- if (status != noErr) {
- PutPascalString("\pCan't create log record iterator: ");
- PutSigned(status);
- PutLine();
- }
- else {
- count = 0;
- while ((logRecordPtr = LogRecordIterate(&cookie)) != NULL) {
- ++count;
- PutPascalString("\p ");
- PutCString((const char *) logRecordPtr->logName);
- PutPascalString("\p at ");
- PutHexLeadingZeros((UInt32) logRecordPtr, 8);
- PutLine();
- }
- LogRecordIterateDispose(&cookie);
- PutUnsigned(count);
- PutPascalString(
- (count == 1) ? "\p LogRecord found" : "\p LogRecords found"
- );
- PutLine();
- /*
- * Second pass does the work.
- */
- status = LogRecordIterateCreate(&cookie);
- if (status == noErr) {
- while ((logRecordPtr = LogRecordIterate(&cookie)) != NULL)
- DCMDDoThisLogRecord(logRecordPtr);
- LogRecordIterateDispose(&cookie);
- }
- }
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * DCMDDoThisLogRecord
- *
- * We have a LogRecord. Fetch a copy of the static part of the record, display the
- * fixed information, then display all LogEntries.
- */
- void
- DCMDDoThisLogRecord(
- LogRecordPtr logRecordPtr
- )
- {
- LogRecord logRecordCopy;
- OSErr status;
- #define LOG (logRecordCopy)
-
- if (logRecordPtr != NULL) {
- PutPascalString("\p• LogRecord \"");
- PutCString((const char *) logRecordPtr->logName);
- PutPascalString("\p\", at ");
- PutHexLeadingZeros((UInt32) logRecordPtr, 8);
- PutLine();
- status = CopyLogRecordInfo(logRecordPtr, &logRecordCopy);
- if (status != noErr) {
- PutPascalString("\pCould not copy log record: ");
- PutSigned(status);
- PutLine();
- }
- else {
- if (LOG.semaphore != 0) {
- PutPascalString("\p ••• Semaphore locked •••\n");
- PutLine();
- }
- if (LOG.lostLockCounter != 0) {
- PutPascalString("\p Lost Semaphore Counter ");
- PutUnsigned(LOG.lostLockCounter);
- PutLine();
- }
- PutPascalString("\p Sequence Counter ");
- PutUnsigned(LOG.sequenceCounter);
- PutPascalString("\p, Flags = ");
- PutHexLeadingZeros(LOG.flags, 8);
- PutPascalString("\p, ");
- PutPascalString(
- ((LOG.flags & kLogDataEnabledMask) != 0)
- ? "\pEnabled"
- : "\pDisabled"
- );
- PutPascalString("\p, Preserve ");
- PutPascalString(
- ((LOG.flags & kLogDataPreserveFirstMask) != 0)
- ? "\pearliest."
- : "\pmost recent."
- );
- PutLine();
- if ((LOG.flags & kLogDataWrapAroundMask) != 0) {
- if (LOG.entryGetIndex < LOG.entryPutIndex) {
- /*
- * +------------+
- * | |
- * | Get Index | Do Put+1 to End (already displayed)
- * | | Do Start to Get (already displayed)
- * | Put Index | Do Get+1 to Put (yet to be displayed)
- * | |
- * +------------+
- */
- DCMDDoLogEntryRange( /* Already displayed */
- logRecordPtr,
- LOG.entryPutIndex + 1,
- LOG.entryMaxIndex - 1
- );
- DCMDDoLogEntryRange( /* Already displayed */
- logRecordPtr,
- 0,
- LOG.entryGetIndex
- );
- DCMDDoLogEntryRange( /* Not yet displayed */
- logRecordPtr,
- LOG.entryGetIndex + 1,
- LOG.entryPutIndex
- );
- }
- else {
- /*
- * +------------+
- * | |
- * | Put Index | Do Put+1 to Get (already displayed)
- * | | Do Get+1 to End (yet to be displayed)
- * | Get Index | Do Start to Put (yet to be displayed)
- * | |
- * +------------+
- */
- DCMDDoLogEntryRange( /* Already displayed */
- logRecordPtr,
- LOG.entryPutIndex + 1,
- LOG.entryGetIndex
- );
- DCMDDoLogEntryRange( /* Not yet displayed */
- logRecordPtr,
- LOG.entryGetIndex + 1,
- LOG.entryMaxIndex - 1
- );
- DCMDDoLogEntryRange( /* Not yet displayed */
- logRecordPtr,
- 0,
- LOG.entryPutIndex
- );
- }
- }
- else {
- /*
- * We haven't wrapped around yet.
- * +------------+
- * | 0 | Untouched
- * | 1 | First real entry
- * | |
- * | Get Index |
- * | | Do Start to Get (already displayed)
- * | Put Index | Do Get+1 to Put (yet to be displayed)
- * | |
- * +------------+
- */
- DCMDDoLogEntryRange( /* Already displayed */
- logRecordPtr,
- 1,
- LOG.entryGetIndex
- );
- DCMDDoLogEntryRange( /* Not yet displayed */
- logRecordPtr,
- LOG.entryGetIndex + 1,
- LOG.entryPutIndex
- );
- }
- PutPascalString("\p• End of \"");
- PutCString((const char *) &LOG.logName);
- PutPascalString("\p\"");
- PutLine();
- }
- }
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * DCMDDoLogEntryRange
- *
- * Process a range of log record entries. Note: the range is inclusive
- */
- void
- DCMDDoLogEntryRange(
- LogRecordPtr logRecordPtr,
- UInt32 startIndex,
- UInt32 endIndex
- )
- {
- LogEntryRecord thisLogEntry;
- DateTimeRec eventDateTime;
- UInt32 residualNanoseconds;
- Str255 work;
- OSErr status;
- #define ENTRY (thisLogEntry)
-
- status = noErr;
- while (status == noErr && startIndex <= endIndex) {
- status = CopyLogEntry(logRecordPtr, startIndex, &thisLogEntry);
- if (status == noErr) {
- /*
- * This is what we've been waiting for.
- */
- LogConvertTimestamp(
- &thisLogEntry,
- &eventDateTime,
- &residualNanoseconds
- );
- PutUnsignedInField(ENTRY.sequence, 5);
- PutPascalString("\p ");
- #if 0 /* Testing */
- PutUnsignedLeadingZeros(eventDateTime.year % 100, 2, '.');
- PutUnsignedLeadingZeros(eventDateTime.month, 2, '.');
- PutUnsignedLeadingZeros(eventDateTime.day, 2, ' ');
- #endif
- PutUnsignedLeadingZeros(eventDateTime.hour, 2, ':');
- PutUnsignedLeadingZeros(eventDateTime.minute, 2, ':');
- PutUnsignedLeadingZeros(eventDateTime.second, 2, '.');
- /* uSec */ PutUnsignedLeadingZeros(residualNanoseconds / 1000L, 6, NUL);
- FormatLogEntryData(&ENTRY, work);
- PutPascalString("\p ");
- PutPascalString(work);
- }
- else if (status == fBsyErr)
- PutPascalString("\p Semaphore Locked");
- else {
- PutSigned(status);
- PutPascalString("\p: strange status");
- }
- PutLine();
- ++startIndex;
- }
- #undef ENTRY
- }
-
- /*
- * Output an n-digit value with leading zeros.
- */
- void
- PutUnsignedLeadingZeros(
- UInt32 value,
- short digits,
- unsigned char terminator
- )
- {
- if (--digits > 0)
- PutUnsignedLeadingZeros(value / 10, digits, NUL);
- PutChar((value % 10) + '0');
- if (terminator != NUL)
- PutChar(terminator);
- }
-
- /*
- * Output a signed decimal longword.
- */
- void
- PutSigned(
- SInt32 value
- )
- {
- if (value < 0) {
- PutChar('-');
- value = (-value);
- }
- PutUnsigned((unsigned long) value);
- }
-
- /*
- * Output an unsigned decimal longword.
- */
- void
- PutUnsigned(
- UInt32 value
- )
- {
- if (value >= 10)
- PutUnsigned(value / 10);
- PutChar((value % 10) + '0');
- }
-
- /*
- * Output a string of hex digits with leading zeros.
- */
- void
- PutHexLeadingZeros(
- unsigned long value,
- short digits
- )
- {
- if (--digits > 0)
- PutHexLeadingZeros(value >> 4, digits);
- value &= 0x0F;
- PutChar((value < 10)
- ? value + '0'
- : (value + ('A' - 10))
- );
- }
-
- /*
- * Output an n-digit decimal value with leading blanks.
- */
- void
- PutUnsignedInField(
- UInt32 value,
- short fieldWidth
- )
- {
- Str15 work;
-
- NumToString(value, work);
- while (work[0] < fieldWidth) {
- PutChar(' ');
- --fieldWidth;
- }
- PutPascalString(work);
- }
-
- void
- PutPascalString(
- ConstStr255Param datum
- )
- {
- dcmdDrawString(datum);
- }
-
- void
- PutCString(
- const char *datum
- )
- {
- char *cp;
-
- for (cp = (char *) datum; *cp != NUL; cp++)
- PutChar(*cp);
- }
-
- void
- PutChar(
- unsigned char datum
- )
- {
- char work[1];
-
- if (datum == '\n')
- PutLine();
- else {
- work[0] = datum;
- dcmdDrawText((StringPtr) work, sizeof (char));
- }
- }
-
- void
- PutLine(void)
- {
- dcmdDrawLine("\p");
- }
-